1   /*
2    * Copyright (C) 2011 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5    * in compliance with the License. You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software distributed under the License
10   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11   * or implied. See the License for the specific language governing permissions and limitations under
12   * the License.
13   */
14  
15  package com.google.common.cache;
16  
17  import com.google.common.annotations.GwtCompatible;
18  import com.google.common.annotations.GwtIncompatible;
19  
20  import java.util.concurrent.ConcurrentLinkedQueue;
21  import java.util.concurrent.atomic.AtomicInteger;
22  
23  /**
24   * Utility {@link RemovalListener} implementations intended for use in testing.
25   *
26   * @author mike nonemacher
27   */
28  @GwtCompatible(emulated = true)
29  class TestingRemovalListeners {
30  
31    /**
32     * Returns a new no-op {@code RemovalListener}.
33     */
34    static <K, V> NullRemovalListener<K, V> nullRemovalListener() {
35      return new NullRemovalListener<K, V>();
36    }
37  
38    /**
39     * Type-inferring factory method for creating a {@link QueuingRemovalListener}.
40     */
41    @GwtIncompatible("ConcurrentLinkedQueue")
42    static <K, V> QueuingRemovalListener<K, V> queuingRemovalListener() {
43      return new QueuingRemovalListener<K,V>();
44    }
45  
46    /**
47     * Type-inferring factory method for creating a {@link CountingRemovalListener}.
48     */
49    static <K, V> CountingRemovalListener<K, V> countingRemovalListener() {
50      return new CountingRemovalListener<K,V>();
51    }
52  
53    /**
54     * {@link RemovalListener} that adds all {@link RemovalNotification} objects to a queue.
55     */
56    @GwtIncompatible("ConcurrentLinkedQueue")
57    static class QueuingRemovalListener<K, V>
58        extends ConcurrentLinkedQueue<RemovalNotification<K, V>> implements RemovalListener<K, V> {
59  
60      @Override
61      public void onRemoval(RemovalNotification<K, V> notification) {
62        add(notification);
63      }
64    }
65  
66    /**
67     * {@link RemovalListener} that counts each {@link RemovalNotification} it receives, and provides
68     * access to the most-recently received one.
69     */
70    static class CountingRemovalListener<K, V> implements RemovalListener<K, V> {
71      private final AtomicInteger count = new AtomicInteger();
72      private volatile RemovalNotification<K, V> lastNotification;
73  
74      @Override
75      public void onRemoval(RemovalNotification<K, V> notification) {
76        count.incrementAndGet();
77        lastNotification = notification;
78      }
79  
80      public int getCount() {
81        return count.get();
82      }
83  
84      public K getLastEvictedKey() {
85        return lastNotification.getKey();
86      }
87  
88      public V getLastEvictedValue() {
89        return lastNotification.getValue();
90      }
91  
92      public RemovalNotification<K, V> getLastNotification() {
93        return lastNotification;
94      }
95    }
96  
97    /**
98     * No-op {@link RemovalListener}.
99     */
100   static class NullRemovalListener<K, V> implements RemovalListener<K, V> {
101     @Override
102     public void onRemoval(RemovalNotification<K, V> notification) {}
103   }
104 }